package com.xw.bo.ks.util;

import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import com.xw.bo.ks.entity.enums.ExceptionEnum;
import com.xw.bo.ks.entity.exception.BoException;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanWrapper;
import org.springframework.beans.BeanWrapperImpl;

import java.beans.PropertyDescriptor;
import java.math.BigDecimal;
import java.util.Date;
import java.util.HashSet;
import java.util.Set;

/**
 * @author： XW -> ~
 * @create： 2023/11/15 10:39
 */
public class XwUtil {

    public static Integer parseToInteger(String formatDate) {
        return parseToInteger(formatDate,0);
    }

    /**
     * 将yyyy-MM-dd HH:mm:ss转为时间戳，
     * yyyy-MM-dd转为凌晨的时间戳或者晚上时间戳，根据timeType判断
     * 凌晨是00:00:00，晚上是23:59:59
     * @param formatDate 时间格式
     * @param timeType 0=不转凌晨或者晚上，1=凌晨，2=晚上
     * @return 时间戳
     */
    public static Integer parseToInteger(String formatDate,int timeType) {
        Date parseDate = DateUtils.parseStrToDate(formatDate, DateUtils.DATE_PATTERN_DEFAULT);

        if (parseDate == null) {
            parseDate = DateUtils.parseStrToDate(formatDate, DateUtils.DATE_FORMAT_yyyyMMdd_H);
            if (timeType == 1){
                parseDate = DateUtil.beginOfDay(parseDate);
            } else if (timeType == 2){
                parseDate = DateUtil.endOfDay(parseDate);
            }
        }

        if (null == parseDate) {
            throw new BoException(ExceptionEnum.DATE_FORMAT_EXCEPTION);
        }

        return getDayTime(parseDate.getTime());
    }

    /**
     * 解析日期，解析不了就抛出异常
     *
     * @param formatDate 解析的时间,yyyy-MM-dd HH:mm:ss或者yyyy-MM-dd
     * @return 1、格式是yyyy-MM-dd HH:mm:ss，解析日期。
     * 2、格式yyyy-MM-dd解析当天开始日期。
     * 3、抛异常
     */
    public static Integer parseToStartInteger(String formatDate) {
        Long startLong = parseToStartLong(formatDate);
        return (int) (startLong / 1000);
    }

    public static Integer parseToStartInteger(Long dateTime) {
        DateTime beginOfDay = DateUtil.beginOfDay(new Date(dateTime));
        return (int) (beginOfDay.getTime() / 1000);
    }

    /**
     * 将yyyyMMdd的int值转换为10位数的时间戳
     * @param ymd yyyyMMdd格式的时间
     * @return 10位时间戳,一天的起始时间戳
     */
    public static Integer parseToStartIntegerByYmd(Integer ymd) {
        if (ymd <= 9999999){
            return ymd;
        }

        String value = ymdToString(ymd);
        if (StringUtils.isEmpty(value)){
            return 0;
        }

        return parseToStartInteger(value);
    }

    public static String ymdToString(Integer ymd){

        if (ymd <= 9999999){
            return "";
        }

        int day = ymd % 100;
        int month = (ymd % 10000) / 100;
        int year = ymd / 10000;

        StringBuilder stringBuilder = new StringBuilder();

        stringBuilder.append(year)
                .append("-")
                .append(month)
                .append("-")
                .append(day);

        return stringBuilder.toString();
    }


    public static Long parseToStartLong(String formatDate) {

        return parseToStartDate(formatDate).getTime();
    }

    /**
     * 解析日期，解析不了就抛出异常
     *
     * @param formatDate 解析的时间,yyyy-MM-dd HH:mm:ss或者yyyy-MM-dd
     * @return 1、格式是yyyy-MM-dd HH:mm:ss，解析日期。
     * 2、格式yyyy-MM-dd解析当天结束日期。
     * 3、抛异常
     */
    public static Integer parseToEndInteger(String formatDate) {
        Long endLong = parseToEndLong(formatDate);
        return (int) (endLong / 1000);
    }

    /**
     * 将yyyyMMdd的int值转换为10位数的时间戳
     * @param ymd yyyyMMdd格式的时间
     * @return 10位时间戳,一天的结束时间戳
     */
    public static Integer parseToEndIntegerByYmd(Integer ymd) {
        if (ymd <= 9999999){
            return ymd;
        }

        String value = ymdToString(ymd);
        if (StringUtils.isEmpty(value)){
            return 0;
        }

        return parseToEndInteger(value);
    }

    public static Integer parseToEndInteger(Long dateTime) {
        Long endLong = DateUtil.endOfDay(new Date(dateTime)).getTime();
        return (int) (endLong / 1000);
    }


    public static Long parseToEndLong(String formatDate) {

        return parseToEndDate(formatDate).getTime();
    }

    public static Date parseToStartDate(String formatDate) {
        return parseToDate(formatDate, true);
    }

    public static Date parseToEndDate(String formatDate) {
        return parseToDate(formatDate, false);
    }

    private static Date parseToDate(String formatDate, boolean isStart) {
        Date parseDate = DateUtils.parseStrToDate(formatDate, DateUtils.DATE_PATTERN_DEFAULT);

        if (parseDate == null) {
            parseDate = DateUtils.parseStrToDate(formatDate, DateUtils.DATE_FORMAT_yyyyMMdd_H);
        }

        if (null == parseDate) {
            throw new BoException(ExceptionEnum.DATE_FORMAT_EXCEPTION);
        }

        if (isStart) {
            parseDate = new Date(DateUtil.beginOfDay(parseDate).getTime());
        } else {
            parseDate = new Date(DateUtil.endOfDay(parseDate).getTime());
        }

        return parseDate;
    }

    /**
     * 将时间戳转换为字符串日期
     *
     * @param time 时间戳
     * @return 字符串日期，格式：yyyy-MM-dd
     */
    public static String getLongDayFormatYmd(Long time) {
        return getDayFormatPattern(time, DateUtils.DATE_FORMAT_yyyyMMdd_H);
    }

    /**
     * 将时间戳转换为字符串日期
     *
     * @param time 时间戳
     * @return 字符串日期，格式：yyyy-MM-dd
     */
    public static String getIntegerDayFormatYmd(Integer time) {
        if (time == null) {
            return "";
        }
        return getLongDayFormatYmd(time.longValue() * 1000L);
    }

    /**
     * 将时间戳转换为字符串日期 yyyy-MM-dd hh:mm:ss
     *
     * @param time 时间戳
     */
    public static String getIntegerDayFormatYmdHms(Integer time) {
        return getIntegerDayFormatYmdHms(time.longValue() * 1000L);
    }

    public static String getIntegerDayFormatYmdHms(Long time) {
        if (time == null) {
            return "";
        }
        return getDayFormatPattern(time, DateUtils.DATE_PATTERN_DEFAULT);
    }

    /**
     * 将时间戳转换为字符串日期
     *
     * @param time    时间戳
     * @param pattern 时间格式
     */
    public static String getIntegerDayFormatYmd(Integer time, String pattern) {
        if (time == null) {
            return "";
        }
        return getDayFormatPattern(time.longValue() * 1000L, pattern);
    }

    public static String getDayFormatPattern(Long time, String pattern) {
        if (time == null) {
            return "";
        }
        return DateUtils.formatDateToString(new Date(time), pattern);
    }

    /**
     * 返回yyyyMMdd格式的数字
     *
     * @param time 时间戳
     * @return 指定格式数字
     */
    public static Integer getDayFormatYmd(Long time) {
        String date = DateUtils.formatDateToString(new Date(time), DateUtils.DATE_FORMAT_yyyyMMdd);
        if (StringUtils.isEmpty(date)) {
            throw new BoException(ExceptionEnum.DATE_FORMAT_EXCEPTION);
        }
        try {
            return Integer.parseInt(date);
        } catch (NumberFormatException e) {
            throw new BoException(ExceptionEnum.NUMBER_CHANGE_EXCEPTION);
        }
    }

    /**
     * 将13位long类型时间戳转换为10位时间戳
     * 非普通的long转int
     *
     * @param time 转换前的值
     * @return 转换后
     */
    public static Integer getDayTime(Long time) {
        if (null == time) {
            return -1;
        }
        time /= 1000L;
        return time.intValue();
    }

    public static Long getDayLongTime(Integer time) {
        if (null == time) {
            return -1L;
        }
        return time.longValue() * 1000L;
    }


    /**
     * 今天的起始日期
     *
     * @return 10位数时间戳
     */
    public static Integer getCurrentStartDayTime() {
        return getStartDayTime(System.currentTimeMillis());
    }

    /**
     * 获取指定时间戳的当天起始日期
     *
     * @param time 13位时间戳
     * @return 指定日期的起始日期前，10时间戳
     */
    public static Integer getStartDayTime(Long time) {
        if (time <= 0) {
            return 0;
        }
        DateTime beginOfDay = DateUtil.beginOfDay(new Date(time));
        return getDayTime(beginOfDay.getTime());
    }

    /**
     * 今天的结束日期
     *
     * @return 10位时间戳
     */
    public static Integer getCurrentEndDayTime() {
        return getEndDayTime(System.currentTimeMillis());
    }

    /**
     * 获取指定时间戳的当天结束日期
     *
     * @param time 13位时间戳
     * @return 指定日期的起始日期前，10时间戳
     */
    public static Integer getEndDayTime(Long time) {
        if (time <= 0) {
            return 0;
        }
        DateTime endOfDay = DateUtil.endOfDay(new Date(time));
        return getDayTime(endOfDay.getTime());
    }


    /**
     * 获取当前10位的时间戳
     *
     * @return 10位时间戳
     */
    public static Integer getCurrentDayTime() {
        return getDayTime(System.currentTimeMillis());
    }

    public static Integer getCurrentDayYmd() {
        return getDayFormatYmd(System.currentTimeMillis());
    }

    /**
     * long类型转int,
     * 需要毫秒的时间戳转int，请找方法getDayTime
     *
     * @param value 值
     * @return int类型
     */
    public static Integer longToInt(Long value) {
        if (null == value) {
            return 0;
        }
        return value.intValue();
    }

    public static Byte intToByte(Integer value) {
        if (null == value) {
            return 0;
        }
        return value.byteValue();
    }

    /**
     * 使用BeanUtils.copyProperties()复制时，去null值
     *
     * @param source 对象
     * @return @return {@link String[] }
     */
    public static String[] nullPropertyNames(Object source) {
        final BeanWrapper src = new BeanWrapperImpl(source);
        PropertyDescriptor[] propertyDescriptor = src.getPropertyDescriptors();
        Set<String> emptyNames = new HashSet<>();
        for (PropertyDescriptor pd : propertyDescriptor) {
            Object srcValue = src.getPropertyValue(pd.getName());
            if (srcValue == null) emptyNames.add(pd.getName());
        }
        String[] result = new String[emptyNames.size()];
        return emptyNames.toArray(result);
    }

    /**
     * 计算服务费
     *
     * @param moneyAmount 金额
     * @param proportion  比例
     * @return 服务费结果
     */
    public static BigDecimal calculateServiceFees(BigDecimal moneyAmount, BigDecimal proportion) {
        if (moneyAmount == null || proportion == null) {
            return BigDecimal.ZERO;
        }
        BigDecimal divide = moneyAmount.multiply(proportion).divide(new BigDecimal(100), BigDecimal.ROUND_DOWN);
        return divide.setScale(3, BigDecimal.ROUND_HALF_UP);
    }


    public static void main(String[] args) {

        Long value = 1706681172793L;
        Integer integer = longToInt(value);

        System.out.println("integer = "+integer);
    }


}
